package com.sjsu.cloudmanager.client.ui;

import com.extjs.gxt.charts.client.Chart;
import com.extjs.gxt.charts.client.model.ChartModel;
import com.extjs.gxt.charts.client.model.axis.XAxis;
import com.extjs.gxt.charts.client.model.axis.YAxis;
import com.extjs.gxt.charts.client.model.charts.AreaChart;
import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.Style;
import com.extjs.gxt.ui.client.data.BaseListLoadResult;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
import com.extjs.gxt.ui.client.widget.layout.RowData;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sjsu.cloudmanager.client.CloudManager;
import com.sjsu.cloudmanager.client.service.CloudLabServiceAsync;
import com.sjsu.cloudmanager.client.ui.model.ComputingMachineBean;

import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: ckempaiah
 * Date: 10/13/11
 * Time: 12:44 AM
 * To change this template use File | Settings | File Templates.
 */
public class MonitoringMainPanel extends LayoutContainer {
    public static final String LAST_12 = "Last 12 hours";
    public static final String LAST_24 = "Last 24 hours";
    private int updateCmd = 10000;

    FormPanel formPanel;

    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);

        FormPanel formPanel = new FormPanel();
        formPanel.setBodyBorder(false);
        //horizontalPanel.setStyleName(Style.HorizontalAlignment);
        ListStore<ComputingMachineBean> machineStore = new ListStore<ComputingMachineBean>(getBaseListLoader());
        final ComboBox<ComputingMachineBean> machineName = new ComboBox<ComputingMachineBean>();
        machineName.setFieldLabel("By Machine");

        machineName.setDisplayField("machineName");
        // machineName.setValueField("computingMachineBean");
        machineName.setStore(machineStore);
        machineName.select(1);
        machineName.setTriggerAction(ComboBox.TriggerAction.ALL);
        formPanel.add(machineName);

        final SimpleComboBox<String> period = new SimpleComboBox<String>();
        period.setFieldLabel("By Period");
        period.add(Arrays.asList(new String[]{LAST_12, LAST_24}));
        period.select(1);
        formPanel.add(period);
        formPanel.setButtonAlign(Style.HorizontalAlignment.LEFT);
        Button button = new Button("Update");
        formPanel.addButton(button);
        add(formPanel);
        final ContentPanel cp = new ContentPanel();
        cp.setHeaderVisible(false);
        cp.setHeight(450);
        cp.setBodyBorder(false);
        cp.setBorders(false);


        button.addSelectionListener(new SelectionListener<ButtonEvent>() {
            @Override
            public void componentSelected(ButtonEvent ce) {
                if (machineName.getValue() != null && period.getSimpleValue() != null) {
                    String name = machineName.getValue().getMachineName();
                    cp.removeAll();
                    String periodValue = period.getSimpleValue();
                    cp.setLayout(new RowLayout(Style.Orientation.VERTICAL));
                    RowData rowData = new RowData(1, .5);
                    rowData.setMargins(new Margins(10));
                    cp.add(getChart("CPU usage for:" + name, periodValue, 100, 10, "#ff0000"), rowData);
                    cp.add(getChart("Memory usage for:" + name, periodValue, 20, 2, "#00aa00"), rowData);
                    cp.layout();
                } else {
                    MessageBox.alert(MessageBox.INFO, "Select Machine and period", null);
                }
            }
        });

        add(cp);
    }

    private Chart getChart(String title, String period, int limit, int step, String color) {
        String url = !CloudManager.isExplorer() ? "../../" : "";
        url += "gxt-225/chart/open-flash-chart.swf";

        final Chart chart = new Chart(url);
        chart.setBorders(true);
        chart.setChartModel(getCharData(title, period, limit, step, color));
        return chart;
    }


    private ChartModel getCharData(String title, String period, int limit, int step, String color) {

        List<String> xLabel = getTimeLabel(period);

        ChartModel cm = new ChartModel(title, "font-size: 14px; font-family: Verdana; align:left;");
        cm.setBackgroundColour("#ffffff");
        XAxis xa = new XAxis();
        xa.setLabels(xLabel);
        cm.setXAxis(xa);
        // cm.setXLegend(new Text("hours"));
        //cm.setYLegend(new Text("percentage"));
        YAxis ya = new YAxis();
        ya.setRange(0, limit, step);

        cm.setYAxis(ya);

        AreaChart area1 = new AreaChart();
        area1.setFillAlpha(0.3f);
        area1.setColour(color);
        area1.setFillColour(color);

        for (int n = 0; n < xLabel.size(); n++) {
            if (n % 2 != 0 && n != 11) {
                area1.addNullValue();
            } else {
                area1.addValues(Random.nextInt(limit));
            }
        }
        cm.addChartConfig(area1);
        return cm;
    }

    private List<String> getTimeLabel(String period) {
        Date date = new Date();
        List<String> xLabel = new ArrayList<String>();
        List<Number> valueList = new ArrayList<Number>();
        DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("MM/dd kk");
        int limit = 12;
        if (LAST_12.equalsIgnoreCase(period)) {
            limit = 12;
        } else {
            limit = 24;
        }
        for (int i = 0; i < limit; i++) {
            date = new Date(date.getTime() - (1 * 60 * 60 * 1000));
            xLabel.add(dateTimeFormat.format(date));
        }
        Collections.reverse(xLabel);
        return xLabel;
    }

    private BaseListLoader<BaseListLoadResult<ModelData>> getBaseListLoader() {
        final CloudLabServiceAsync service = (CloudLabServiceAsync) Registry.get(CloudManager.CLOUD_LAB_SERVICE);

        RpcProxy<List<ComputingMachineBean>> proxy = new RpcProxy<List<com.sjsu.cloudmanager.client.ui.model.ComputingMachineBean>>() {
            @Override
            public void load(Object loadConfig,
                             AsyncCallback<List<com.sjsu.cloudmanager.client.ui.model.ComputingMachineBean>> callback) {
                service.getComputingMachineBeanList(callback);
            }
        };
        final BaseListLoader<BaseListLoadResult<ModelData>> loader = new BaseListLoader<BaseListLoadResult<ModelData>>(proxy);
        return loader;


    }
}
